package com.yuexunit.finance.project.action.v1.dto;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.yuexunit.core.BusinessException;
import com.yuexunit.finance.common.util.BeanUtils;
import com.yuexunit.finance.common.util.CollectionUtils;
import com.yuexunit.finance.context.FinanceConstant;
import com.yuexunit.finance.context.FinanceSessionContext;
import com.yuexunit.finance.member.entity.EnterpriseEntity;
import com.yuexunit.finance.member.entity.LogisticsCompanyEntity;
import com.yuexunit.finance.member.service.EnterpriseService;
import com.yuexunit.finance.member.service.LogisticsCompanyService;
import com.yuexunit.finance.project.action.v1.model.Insurance;
import com.yuexunit.finance.project.action.v1.model.input.InsuranceCoverageParams;
import com.yuexunit.finance.project.action.v1.model.output.ConstractCallbackDetail;
import com.yuexunit.finance.project.action.v1.model.output.FinanceContractDetail;
import com.yuexunit.finance.project.action.v1.model.output.FinanceFilesInfoDetail;
import com.yuexunit.finance.project.action.v1.model.output.InsuranceCoverageDetail;
import com.yuexunit.finance.project.action.v1.model.output.InsuranceCoverageLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.InsuranceDetail;
import com.yuexunit.finance.project.action.v1.model.output.InsuranceLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.SupervisionContractDetail;
import com.yuexunit.finance.project.entity.ContainerInventoryEntity;
import com.yuexunit.finance.project.entity.FinanceApplicationEntity;
import com.yuexunit.finance.project.entity.FinanceAuditEntity;
import com.yuexunit.finance.project.entity.FinanceBulkstockEntity;
import com.yuexunit.finance.project.entity.FinanceConstractCallBackInfoEntity;
import com.yuexunit.finance.project.entity.FinanceContractEntity;
import com.yuexunit.finance.project.entity.FinanceFilesInfoEntity;
import com.yuexunit.finance.project.entity.InsuranceCoverageBulkstockEntity;
import com.yuexunit.finance.project.entity.InsuranceCoverageContainerEntity;
import com.yuexunit.finance.project.entity.InsuranceCoverageEntity;
import com.yuexunit.finance.project.entity.InsuranceEntity;
import com.yuexunit.finance.project.entity.SupervisionContractEntity;
import com.yuexunit.finance.project.entity.lexicon.FinanceSegmentEnum;
import com.yuexunit.finance.project.entity.lexicon.OperatorRoleEnum;
import com.yuexunit.finance.project.entity.lexicon.PurchaseEnum;
import com.yuexunit.finance.project.service.ContainerInventoryService;
import com.yuexunit.finance.project.service.FinanceApplicationService;
import com.yuexunit.finance.project.service.FinanceBulkstockService;
import com.yuexunit.finance.project.service.FinanceFilesInfoService;
import com.yuexunit.finance.project.service.InsuranceCoverageBulkstockService;
import com.yuexunit.finance.project.service.InsuranceCoverageContainerService;
import com.yuexunit.finance.project.service.InsuranceCoverageService;
import com.yuexunit.finance.system.entity.SignFileInfoEntity;
import com.yuexunit.finance.system.service.SignFileInfoService;
import com.yuexunit.inject.ComponentFactory;
import com.yuexunit.organization.OrganizationActionApi;
import com.yuexunit.organization.dto.InquireCompanyInfoOutput;
import com.yuexunit.organization.dto.InquireEmployeeDetailOutput;
import com.yuexunit.util.DateUtil;

/**
 * @author zeng hui wu 2015年10月8日
 */
public class FinanceContractCastor {

	public static InsuranceEntity fromFinanceAudit(FinanceApplicationEntity finance, FinanceAuditEntity audit) {
		if (StringUtils.isBlank(audit.getInsurer()) || StringUtils.isBlank(audit.getInsuranceType()) || audit.getInsuranceAmount() == null || audit.getForceAmount() == null) {
			throw new BusinessException("投保情况下,保单相关信息都不允许为空");
		}
		OrganizationActionApi organizationAction = ComponentFactory.loadClass(OrganizationActionApi.class);
		InquireEmployeeDetailOutput employeeInfo = organizationAction.inquireCurrentAccountEmployeeInfo();
		InquireCompanyInfoOutput companyInfo = organizationAction.inquireCompanyInfo();

		InsuranceEntity insurance = new InsuranceEntity();
		insurance.setFinanceId(finance.getFinanceId());
		insurance.setFinanceNumber(finance.getFinanceNumber());
		insurance.setDeliverAddress(finance.getFullDeliverAddress());
		insurance.setReceiveAddress(finance.getFullReceiveAddress());
		if (employeeInfo != null) {
			insurance.setApplicant(employeeInfo.getName());
		} else {
			insurance.setApplicant(FinanceSessionContext.getAccountFullName());
		}
		if (companyInfo != null) {
			insurance.setApplicantAddress(companyInfo.getAddress());
			insurance.setApplicantDepartment(companyInfo.getName());
		}
		insurance.setApplicantId(null);
		insurance.setApplicantTenantId(FinanceConstant.DEFAULT_PLATFORM_WEB_TENANT);
		insurance.setMold(OperatorRoleEnum.PLATFORM);
		insurance.setInsuranceCompany(audit.getInsurer());
		insurance.setInsuranceNumber(audit.getInsuranceNumber());
		insurance.setInsuranceDate(DateUtil.todayInt());
		insurance.setPurchase(PurchaseEnum.PLATFORM);
		insurance.setTotalAmount(audit.getForceAmount());
		insurance.setTotalPremium(audit.getInsuranceAmount());
		return insurance;
	}
	
	public static InsuranceEntity fromFinanceApplicationEntity(FinanceApplicationEntity finance) {
		EnterpriseService enterpriseService = ComponentFactory.loadClass(EnterpriseService.class);
		EnterpriseEntity enterprise = enterpriseService.inquireEnterprise(finance.getEnterpriseId());

		InsuranceEntity insurance = new InsuranceEntity();
		insurance.setFinanceId(finance.getFinanceId());
		insurance.setFinanceNumber(finance.getFinanceNumber());
		insurance.setDeliverAddress(finance.getFullDeliverAddress());
		insurance.setReceiveAddress(finance.getFullReceiveAddress());
		insurance.setApplicant(enterprise.getLegalPerson());
		insurance.setApplicantAddress(enterprise.getAddress());
		insurance.setApplicantDepartment(enterprise.getEnterpriseName());
		insurance.setApplicantId(null);
		insurance.setApplicantTenantId(finance.getEnterpriseId());
		insurance.setMold(OperatorRoleEnum.ENTERPRISE);
		insurance.setInsuranceCompany(finance.getEnterpriseInsurer());
		insurance.setInsuranceNumber(finance.getEnterpriseInsuranceNumber());
		insurance.setInsuranceDate(DateUtil.todayInt());
		insurance.setPurchase(PurchaseEnum.AGENT);
		insurance.setTotalAmount(finance.getEnterpriseForceAmount());
		insurance.setTotalPremium(finance.getEnterpriseInsuranceAmount());
		return insurance;
	}
	
	public static InsuranceCoverageEntity fromFinanceApplicationEntity(InsuranceEntity insurance, FinanceApplicationEntity finance) {
		InsuranceCoverageEntity coverage = new InsuranceCoverageEntity();
		coverage.setCoverageName(finance.getEnterpriseInsuranceType());
		coverage.setInsuranceAmount(finance.getEnterpriseForceAmount());
		coverage.setInsuranceId(insurance.getInsuranceId());
		coverage.setPremium(finance.getEnterpriseInsuranceAmount());
		return coverage;
	}
	
	public static List<InsuranceCoverageBulkstockEntity> fromFinanceApplicationEntity(InsuranceCoverageEntity coverage, FinanceApplicationEntity finance) {
		FinanceBulkstockService financeBulkstockService = ComponentFactory.loadClass(FinanceBulkstockService.class);
		List<FinanceBulkstockEntity> bulkstocks = financeBulkstockService.inquireFinanceBulkstockList(finance.getFinanceId());
		List<InsuranceCoverageBulkstockEntity> results = new ArrayList<>();
		for (FinanceBulkstockEntity b : bulkstocks) {
			InsuranceCoverageBulkstockEntity a = new InsuranceCoverageBulkstockEntity();
			a.setInsuranceId(coverage.getInsuranceId());
			a.setInsuranceCoverageId(coverage.getInsuranceCoverageId());
			a.setBulkstockId(b.getBulkstockId());
			results.add(a);
		}
		return results;
	}

	public static InsuranceCoverageEntity fromFinanceAudit(InsuranceEntity insurance, FinanceAuditEntity audit) {
		InsuranceCoverageEntity coverage = new InsuranceCoverageEntity();
		coverage.setCoverageName(audit.getInsuranceType());
		coverage.setInsuranceAmount(audit.getForceAmount());
		coverage.setInsuranceId(insurance.getInsuranceId());
		coverage.setPremium(audit.getInsuranceAmount());
		return coverage;
	}

	public static List<InsuranceCoverageBulkstockEntity> fromFinanceAudit(InsuranceCoverageEntity coverage, FinanceAuditEntity audit) {
		FinanceBulkstockService financeBulkstockService = ComponentFactory.loadClass(FinanceBulkstockService.class);
		List<FinanceBulkstockEntity> bulkstocks = financeBulkstockService.inquireFinanceBulkstockList(audit.getFinanceId());
		List<InsuranceCoverageBulkstockEntity> results = new ArrayList<>();
		for (FinanceBulkstockEntity b : bulkstocks) {
			InsuranceCoverageBulkstockEntity a = new InsuranceCoverageBulkstockEntity();
			a.setInsuranceId(coverage.getInsuranceId());
			a.setInsuranceCoverageId(coverage.getInsuranceCoverageId());
			a.setBulkstockId(b.getBulkstockId());
			results.add(a);
		}
		return results;
	}

	/** 保险信息 */
	public static InsuranceEntity fromInsurance(FinanceApplicationEntity finance, Insurance params) {
		InsuranceEntity insurance = new InsuranceEntity();
		BeanUtils.copyProperties(params, insurance);
		insurance.setInsuranceDate(DateUtil.parseDateInt(params.getInsuranceDate()));
		insurance.setFinanceNumber(finance.getFinanceNumber());
		insurance.setDeliverAddress(finance.getFullDeliverAddress());
		insurance.setReceiveAddress(finance.getFullReceiveAddress());
		insurance.setMold(OperatorRoleEnum.valueOf(params.getMold()));
		insurance.setPurchase(PurchaseEnum.valueOf(params.getPurchase()));
		insurance.setOverRemark(params.getOverRemark());
		if (OperatorRoleEnum.ENTERPRISE == insurance.getMold()) {
			EnterpriseService enterpriseService = ComponentFactory.loadClass(EnterpriseService.class);
			EnterpriseEntity enterprise = enterpriseService.inquireEnterprise(insurance.getApplicantId());
			insurance.setApplicantDepartment(enterprise.getEnterpriseName());
			insurance.setApplicantTenantId(enterprise.getTenantId());
		} else if (OperatorRoleEnum.LOGISTICS == insurance.getMold()) {
			LogisticsCompanyService logisticsCompanyService = ComponentFactory.loadClass(LogisticsCompanyService.class);
			LogisticsCompanyEntity logisticsCompany = logisticsCompanyService.inquireLogisticsCompanyDetail(insurance.getApplicantId());
			insurance.setApplicantDepartment(logisticsCompany.getCompanyName());
			insurance.setApplicantTenantId(logisticsCompany.getTenantId());
		} else if (OperatorRoleEnum.PLATFORM == insurance.getMold()) {
			insurance.setApplicantId(null);
			insurance.setApplicantTenantId(FinanceConstant.DEFAULT_PLATFORM_WEB_TENANT);
		} else {
			insurance.setApplicantId(null);
			insurance.setApplicantTenantId(null);
		}
		return insurance;
	}

	/** 险种信息 */
	public static InsuranceCoverageEntity fromInsuranceCoverage(InsuranceEntity insurance, InsuranceCoverageParams params) {
		InsuranceCoverageEntity coverage = new InsuranceCoverageEntity();
		BeanUtils.copyProperties(params, coverage);
		return coverage;
	}

	/** 保险货物信息 */
	public static List<InsuranceCoverageBulkstockEntity> fromInsuranceBulkstock(InsuranceCoverageEntity coverage, InsuranceCoverageParams params) {
		List<InsuranceCoverageBulkstockEntity> bulkstocks = new ArrayList<>();
		for (int i = 0; i < params.getBulkstockId().length; i++) {
			InsuranceCoverageBulkstockEntity bulkstock = new InsuranceCoverageBulkstockEntity();
			bulkstock.setInsuranceId(coverage.getInsuranceId());
			bulkstock.setInsuranceCoverageId(coverage.getInsuranceCoverageId());
			bulkstock.setBulkstockId(CollectionUtils.getArrayIndexValue(params.getBulkstockId(), i));
			bulkstocks.add(bulkstock);
		}
		return bulkstocks;
	}

	/** 保险货箱信息 */
	public static List<InsuranceCoverageContainerEntity> fromInsuranceContainer(InsuranceCoverageEntity coverage, InsuranceCoverageParams params) {
		List<InsuranceCoverageContainerEntity> containers = new ArrayList<>();
		for (int i = 0; i < params.getInventoryId().length; i++) {
			InsuranceCoverageContainerEntity container = new InsuranceCoverageContainerEntity();
			container.setInsuranceId(coverage.getInsuranceId());
			container.setInsuranceCoverageId(coverage.getInsuranceCoverageId());
			container.setInventoryId(CollectionUtils.getArrayIndexValue(params.getInventoryId(), i));
			containers.add(container);
		}
		return containers;
	}

	public static InsuranceDetail toFinanceInsuranceDetail(InsuranceEntity entity) {
		InsuranceDetail info = new InsuranceDetail();
		BeanUtils.copyProperties(entity, info);
		info.setInsuranceState(entity.getInsuranceState().ordinal());
		info.setInsuranceDate(DateUtil.formatDate(entity.getInsuranceDate()));
		info.setMold(entity.getMold().ordinal());
		info.setPurchase(entity.getPurchase().ordinal());

		InsuranceCoverageService insuranceCoverageService = ComponentFactory.loadClass(InsuranceCoverageService.class);
		InsuranceCoverageBulkstockService insuranceCoverageBulkstockService = ComponentFactory.loadClass(InsuranceCoverageBulkstockService.class);
		InsuranceCoverageContainerService insuranceCoverageContainerService = ComponentFactory.loadClass(InsuranceCoverageContainerService.class);
		FinanceBulkstockService financeBulkstockService = ComponentFactory.loadClass(FinanceBulkstockService.class);
		ContainerInventoryService containerInventoryService = ComponentFactory.loadClass(ContainerInventoryService.class);

		List<InsuranceCoverageEntity> coverages = insuranceCoverageService.inquireInsuranceCoverageList(entity.getInsuranceId());
		for (InsuranceCoverageEntity coverage : coverages) {
			InsuranceCoverageLineInfo lineInfo = new InsuranceCoverageLineInfo();
			BeanUtils.copyProperties(coverage, lineInfo);
			List<Long> bulkstockIds = insuranceCoverageBulkstockService.inquireGroupBulkstockId(coverage.getInsuranceCoverageId());
			if (!bulkstockIds.isEmpty()) {
				List<FinanceBulkstockEntity> bulkstocks = financeBulkstockService.inquireFinanceBulkstockList(bulkstockIds.toArray(new Long[bulkstockIds.size()]));
				for (FinanceBulkstockEntity fbe : bulkstocks) {
					lineInfo.getBulkstockNames().add(fbe.getBulkstockName());
				}
			}
			List<Long> inventoryIds = insuranceCoverageContainerService.inquireGroupInventoryId(coverage.getInsuranceCoverageId());
			if (!inventoryIds.isEmpty()) {
				List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(inventoryIds.toArray(new Long[inventoryIds.size()]));
				for (ContainerInventoryEntity cie : inventories) {
					lineInfo.getCaseNumbers().add(cie.getCaseNumber());
				}
			}
			info.getInsuranceCoverages().add(lineInfo);
		}
		return info;
	}

	public static InsuranceCoverageDetail toInsuranceCoverageDetail(InsuranceCoverageEntity entity) {
		InsuranceCoverageDetail info = new InsuranceCoverageDetail();
		BeanUtils.copyProperties(entity, info);

		InsuranceCoverageBulkstockService insuranceCoverageBulkstockService = ComponentFactory.loadClass(InsuranceCoverageBulkstockService.class);
		InsuranceCoverageContainerService insuranceCoverageContainerService = ComponentFactory.loadClass(InsuranceCoverageContainerService.class);
		FinanceBulkstockService financeBulkstockService = ComponentFactory.loadClass(FinanceBulkstockService.class);
		ContainerInventoryService containerInventoryService = ComponentFactory.loadClass(ContainerInventoryService.class);
		List<Long> bulkstockIds = insuranceCoverageBulkstockService.inquireGroupBulkstockId(entity.getInsuranceCoverageId());
		if (!bulkstockIds.isEmpty()) {
			List<FinanceBulkstockEntity> bulkstocks = financeBulkstockService.inquireFinanceBulkstockList(bulkstockIds.toArray(new Long[bulkstockIds.size()]));
			for (FinanceBulkstockEntity fbe : bulkstocks) {
				info.getBulkstocks().add(BulkstockCastor.toFinanceBulkstock(fbe));
			}
		}
		List<Long> inventoryIds = insuranceCoverageContainerService.inquireGroupInventoryId(entity.getInsuranceCoverageId());
		if (!inventoryIds.isEmpty()) {
			List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(inventoryIds.toArray(new Long[inventoryIds.size()]));
			for (ContainerInventoryEntity cie : inventories) {
				info.getContainers().add(BulkstockCastor.toContainerInventory(cie, Boolean.FALSE));
			}
		}
		return info;
	}

	public static InsuranceLineInfo toFinanceInsuranceLineInfo(InsuranceEntity entity) {
		InsuranceLineInfo info = new InsuranceLineInfo();
		BeanUtils.copyProperties(entity, info);
		info.setInsuranceState(entity.getInsuranceState().ordinal());
		info.setInsuranceDate(DateUtil.formatDate(entity.getInsuranceDate()));
		info.setMold(entity.getMold().ordinal());

		InsuranceCoverageService insuranceCoverageService = ComponentFactory.loadClass(InsuranceCoverageService.class);
		List<InsuranceCoverageEntity> coverages = insuranceCoverageService.inquireInsuranceCoverageList(entity.getInsuranceId());
		for (InsuranceCoverageEntity coverage : coverages) {
			info.getCoverageNames().add(coverage.getCoverageName());
			info.getInsuranceAmounts().add(coverage.getInsuranceAmount());
			info.getPremiums().add(coverage.getPremium());
		}
		return info;
	}

	// ========================================================================================================================================================================//
	/** 融资合同 */
	public static FinanceContractEntity fromFinanceContract(Long financeId, String financeNumber, String contractSignDate, String deliver, String receive, String financeContractSerialNumber, Integer contractType) {
		FinanceContractEntity financeContractEntity = new FinanceContractEntity();
		financeContractEntity.setFinanceId(financeId);
		financeContractEntity.setFinanceNumber(financeNumber);
		financeContractEntity.setContractSignDate(DateUtil.parseDateInt(contractSignDate));
		financeContractEntity.setDeliver(deliver);
		financeContractEntity.setReceive(receive);
		financeContractEntity.setFinanceContractSerialNumber(financeContractSerialNumber);
		if (contractType != null) {
			financeContractEntity.setContractType(contractType);
		}
		return financeContractEntity;
	}

	/** 融资合同 */
	public static FinanceContractDetail toFinanceContractDetail(FinanceContractEntity entity) {
		FinanceFilesInfoService financeFilesInfoService = ComponentFactory.loadClass(FinanceFilesInfoService.class);
		SignFileInfoService signFileInfoService = ComponentFactory.loadClass(SignFileInfoService.class);
		FinanceApplicationService financeApplicationService = ComponentFactory.loadClass(FinanceApplicationService.class);
		
		FinanceContractDetail detail = new FinanceContractDetail();
		if (entity != null && entity.getContractType() != null) {
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(entity.getFinanceId());
			BeanUtils.copyProperties(entity, detail);
			detail.setIsSign(finance.getIsSign());
			detail.setContractUploadDate(DateUtil.formatDate(entity.getContractUploadDate()));
			detail.setContractSignDate(DateUtil.formatDate(entity.getContractSignDate()));
			detail.setMaterials(FinanceMaterialCastor.toSegmentMaterials(entity.getFinanceId(), entity.getFinanceContractId(), FinanceSegmentEnum.FINANCE_CONTRACT));
			List<FinanceFilesInfoEntity> ffies = null;
			if (entity.getContractType() == 4) {
				ffies = financeFilesInfoService.inquireFinanceFilesInfoList(entity.getFinanceId(), entity.getFinanceContractId());
			} else {
				ffies = financeFilesInfoService.inquireFinanceFilesInfoList(entity.getFinanceId(), null);
			}
			List<FinanceFilesInfoDetail> ffids = new ArrayList<>();
			for (FinanceFilesInfoEntity ffie : ffies) {
				FinanceFilesInfoDetail ffid = new FinanceFilesInfoDetail();
				BeanUtils.copyProperties(ffie, ffid);
				StringBuffer sb = new StringBuffer();
				StringBuffer sb1 = new StringBuffer();
				StringBuffer sb2 = new StringBuffer();
				for (String s : ffie.getFilesUuid().split(",")) {
					SignFileInfoEntity sfie = signFileInfoService.inquireSignFileInfo(s);
					if (sfie == null) {
						continue;
					}
					sb2.append(sfie.getFilesSign() + ",");
					sb1.append(sfie.getMsg() + ",");
					sb.append(sfie.getFileSignState().ordinal() + ",");
				}
				if (sb != null && sb.length() > 0) {
					sb = sb.deleteCharAt(sb.length() - 1);
					sb1 = sb1.deleteCharAt(sb1.length() - 1);
					sb2 = sb2.deleteCharAt(sb2.length() - 1);
				}
				ffid.setFileSignState(sb.toString());
				ffid.setMsg(sb1.toString());
				ffid.setIsSign(sb2.toString());
				ffids.add(ffid);
			}
			detail.setFinanceFilesInfoList(ffids);
		}
		return detail;
	}

	// ========================================================================================================================================================================//
	/** 监管合同 */
	public static SupervisionContractEntity fromSupervisionContract(Long financeId, String financeNumber, String contractSignDate, Long logisticsCompanyId, String logisticsCompanyName) {
		SupervisionContractEntity entity = new SupervisionContractEntity();
		entity.setFinanceId(financeId);
		entity.setFinanceNumber(financeNumber);
		entity.setContractSignDate(DateUtil.parseDateInt(contractSignDate));
		entity.setLogisticsCompanyId(logisticsCompanyId);
		entity.setLogisticsCompanyName(logisticsCompanyName);
		return entity;
	};

	/** 监管合同 */
	public static SupervisionContractDetail toSupervisionContractDetail(SupervisionContractEntity entity) {
		SupervisionContractDetail detail = new SupervisionContractDetail();
		if (entity != null) {
			BeanUtils.copyProperties(entity, detail);
			detail.setContractUploadDate(DateUtil.formatDate(entity.getContractUploadDate()));
			detail.setContractSignDate(DateUtil.formatDate(entity.getContractSignDate()));
			detail.setMaterials(FinanceMaterialCastor.toSegmentMaterials(entity.getFinanceId(), entity.getSupervisionContractId(), FinanceSegmentEnum.SUPERVISE_CONTRACT));
		}
		return detail;
	}

	/** 融资合同打回信息 */
	public static ConstractCallbackDetail toConstractCallbackDetail(FinanceConstractCallBackInfoEntity entity) {
		FinanceApplicationService financeApplicationService = ComponentFactory.loadClass(FinanceApplicationService.class);
		ConstractCallbackDetail detail = new ConstractCallbackDetail();
		BeanUtils.copyProperties(entity, detail);
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(entity.getFinanceId());
		if (finance == null) {
			return null;
		}
		detail.setEnterpriseName(finance.getEnterpriseName());
		detail.setFinanceNumber(finance.getFinanceNumber());
		return detail;
	}
}
